#ifndef VECTOR3_H
#define VECTOR3_H

#include "bga/system/Tuple.h"

/**
 * \namespace bga
 * \brief API namespace
 */
namespace bga
{

/**
 * \class Vector
 * \brief this class represents a Vector of 3 Elements
 */
template< typename T>
class Vector3 : public Tuple<3, T>
{
    public:

        /**
         * Default Constructor
         */
        Vector3();

        /**
         * Constructor unsing fields
         * \param x : x value
         * \param y : y value
         * \param z : z value
         */
        Vector3(T x, T y, T z);

        /**
         * Copy Constructor
         */
        Vector3(const Vector3<T>& vector);

        /**
         * Destructor
         */
        virtual ~Vector3();

        T getX() const ;
        T getY() const ;
        T getZ() const ;

        void setX(T X);
        void setY(T Y);
        void setZ(T Z);

        void setXYZ(T X, T Y, T Z);

        double getNorm() const;

        void normalize();
        static Vector3<T> normalize(const Vector3<T>& aNormer);

        static Vector3<T> crossProduct(const Vector3<T>& v1, const Vector3<T>& v2);
        void crossProduct(const Vector3<T>& V);

        Vector3<T> operator+(const Vector3<T> &V) const;
        Vector3<T>& operator+=(const Vector3<T> &V);

        Vector3<T> operator-(const Vector3<T> &V) const;
        Vector3<T>& operator-=(const Vector3<T> &V);

        template< typename U >
        Vector3<T> operator*(U value) const;
        double operator*(const Vector3<T>& v) const;

        /**
         * Operator needed to assign new value to the current vector
         * \param v : Vector to assign to current vector
         */
        Vector3<T>& operator=(const Vector3<T>& v);

};

typedef Vector3<int>    Vector3i;
typedef Vector3<float>  Vector3f;
typedef Vector3<double> Vector3d;

}

#include "bga/math/Vector3.inl"



#endif // VECTOR3_H
